package co.fitstart.admin.web.controller.course;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.BusinessException;
import com.demo2do.core.support.Page;
import com.demo2do.core.support.Result;
import com.demo2do.core.utils.DateFormatUtils;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.utils.StringUtils;
import com.demo2do.core.web.utils.WebUtils;

import co.fitstart.admin.entity.search.OnlineRoundSearch;
import co.fitstart.admin.handler.ZipHandler;
import co.fitstart.admin.service.DataService;
import co.fitstart.admin.service.OnlineRoundService;
import co.fitstart.admin.service.ProductService;
import co.fitstart.admin.web.interceptor.MenuSetting;
import co.fitstart.admin.web.view.DownloadTemplateView;
import co.fitstart.admin.web.view.ExcelTemplateView;
import co.fitstart.entity.course.CourseType;
import co.fitstart.entity.course.round.CourseRound;
import co.fitstart.entity.course.round.CourseRoundGroup;
import co.fitstart.entity.course.round.CourseRoundResource;
import co.fitstart.entity.order.OrderInvestigateRecord;
import co.fitstart.entity.product.Product;

/**
 * 
 * @author lidan
 * @author mohanlan
 */
@Controller
@RequestMapping("/online-rounds")
@MenuSetting("menu-course")
public class OnlineRoundController {
    
    private static final Logger logger = LoggerFactory.getLogger(OnlineRoundController.class);
    
    @Autowired
    private OnlineRoundService onlineRoundService;
    
    @Autowired
    @Qualifier("dataService")
    private DataService<CourseRoundResource> dataService;
    
    @Autowired
    private ProductService productService;
    
    @Autowired
    @Qualifier("dataService")
    private DataService<CourseRoundGroup> courseRoundGroupService;
    
    @Value("#{config['file.upload.path']}")
    private String uploadPath;
    
    @Autowired
    private ZipHandler zipHandler;
    
    /**
     * 
     * @param page
     * @param request
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET)
    @MenuSetting("submenu-online-course-arrange")
    public ModelAndView list(Page page, HttpServletRequest request){

        ModelAndView modelAndView = new ModelAndView("course/online/online-round-list");
        
        List<CourseRound> courseRounds = onlineRoundService.list(CourseType.ONLINE, page);
        
        modelAndView.addObject("courseRounds", courseRounds);

        modelAndView.addObject("page", page);
        
        modelAndView.addObject("refer", "list");
        modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page"));
        
        return modelAndView;
    }
    
   
    
    /**
     * 
     * @param roundCode
     * @return
     */
    @RequestMapping(value = "/{roundCode}/rounds/search", method = RequestMethod.GET)
    public ModelAndView search(@PathVariable("roundCode") String roundCode,
                               @RequestParam("grouped") boolean grouped,
                               @RequestParam(value = "group", required = false) String group) {
        ModelAndView modelAndView = new ModelAndView("course/online/online-round-search");
        
        modelAndView.addObject("roundCode", roundCode);
        modelAndView.addObject("grouped", grouped);
        modelAndView.addObject("group", group);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param roundCode
     * @param onlineRoundSearch
     * @param investigated
     * @param page
     * @param request
     * @return
     */
    @RequestMapping(value = "/{roundCode}/rounds", method = RequestMethod.GET, params = "filter")
    @MenuSetting("submenu-online-course-arrange")
    public ModelAndView onSearch(@PathVariable("roundCode") String roundCode,
                                 OnlineRoundSearch onlineRoundSearch,
                                 @RequestParam(value = "group", required = false) String groupName,
                                 Page page,
                                 HttpServletRequest request) {
        ModelAndView modelAndView = new ModelAndView("course/online/view/online-round-view");
        
        modelAndView.addObject("roundCode", roundCode);
        
        List<CourseRound> courseRounds = onlineRoundService.search(onlineRoundSearch, groupName, page);
        
        modelAndView.addObject("courseRounds", courseRounds);
        
        CourseRoundResource courseRoundResource = onlineRoundService.loadCourseRoundResource(roundCode);
        modelAndView.addObject("courseRoundResource", courseRoundResource);
        
        modelAndView.addObject("page", page);
        
        modelAndView.addObject("refer", "search");
        modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page"));
        
        return modelAndView;
    }
    
    /**
     * Display edit remarks
     * 
     * @param roundCode
     * @param roundId
     * @return
     */
    @RequestMapping(value = "/{roundCode}/rounds/{roundId}/remarks", method = RequestMethod.GET)
    public ModelAndView remarks(@PathVariable("roundCode") String roundCode,
                                @PathVariable("roundId") Long roundId){
        
        ModelAndView modelAndView = new ModelAndView("course/online/online-round-remark");
        
        CourseRound courseRound = onlineRoundService.loadCourseRound(roundId);
        
        modelAndView.addObject("courseRound", courseRound);
        
        return modelAndView;
        
    }
    
    /**
     * Do edit remarks
     * 
     * @param roundCode
     * @param roundId
     * @param remarks
     * @return
     */
    @RequestMapping(value = "/{roundCode}/rounds/{roundId}/remarks", method = RequestMethod.PATCH)
    public @ResponseBody String onRemarks(@PathVariable("roundCode") String roundCode,
                                          @PathVariable("roundId") Long roundId,
                                          @RequestParam(value = "remarks") String remarks){
        
        Result result = new Result();
        
        try{
            
            CourseRound courseRound = onlineRoundService.loadCourseRound(roundId);
            onlineRoundService.editRemarks(courseRound, remarks);
            
            result.success().message("修改课程备注成功");
            
        }catch(Exception e){
            
            logger.error("onRemarks() error", e);
            
            result.fail().message("修改课程备注失败");
            
        }
        
        return JsonUtils.toJsonString(result);
        
    }
    
    /**
     * Display edit remarks
     * 
     * @param roundCode
     * @param roundId
     * @return
     */
    @RequestMapping(value = "/{roundCode}/rounds/{roundId}/transfer-camp", method = RequestMethod.GET)
    public ModelAndView transferCamp(@PathVariable("roundCode") String roundCode,
                                     @PathVariable("roundId") Long roundId){
        
        ModelAndView modelAndView = new ModelAndView("course/online/online-round-transfer-camp");
        
        CourseRound courseRound = onlineRoundService.loadCourseRound(roundId);
        
        modelAndView.addObject("courseRound", courseRound);
        
        return modelAndView;
        
    }
    
    /**
     * Do transfer camp
     * 
     * @param roundCode
     * @param roundId
     * @param inputString
     * @return
     */
    @RequestMapping(value = "/{roundCode}/rounds/{roundId}/transfer-camp", method = RequestMethod.PATCH)
    public @ResponseBody String onTransferCamp(@PathVariable("roundCode") String roundCode,
                                          @PathVariable("roundId") Long roundId,
                                          @RequestParam(value = "inputString") String inputString){
        
        Result result = new Result();
        
        try{
            
            CourseRound courseRound = onlineRoundService.loadCourseRound(roundId);
            
            String[] inputResult = StringUtils.split(inputString, "|");
            
            Product product = productService.load(Product.class, new Long(inputResult[0]));
            
            onlineRoundService.transferCamp(courseRound, product, inputResult[1]);
            
            result.success().message("转营成功");
            
        } catch (BusinessException e) {
            result.fail().message(e.getMessage());
        } catch(Exception e){
            
            logger.error("onTransferCamp() error", e);
            
            result.fail().message("转营失败");
            
        }
        
        return JsonUtils.toJsonString(result);
        
    }
    
    /**
     * Do export camp
     * @param roundCode
     * @return
     */
    @RequestMapping(value = "/{roundCode}/export", method = RequestMethod.GET)
    public ModelAndView onExport(@PathVariable("roundCode") String roundCode) {
        
        String date = DateFormatUtils.format(new Date(), "yyyy-MM-dd");
        String fileName = "online-student-" + date + ".xls";
        ModelAndView modelAndView = new ModelAndView(new ExcelTemplateView("camp.xls", fileName));
        
        Map<String, List<OrderInvestigateRecord>> orderInvestigateRecords = onlineRoundService.getOrderInvestigateRecord(roundCode);
        
        modelAndView.addObject("orderInvestigateRecords", orderInvestigateRecords);
        
        int totalAmount = 0;
        Map<String, Integer> total = new HashMap<String, Integer>();
        for(String key : orderInvestigateRecords.keySet()) {
            total.put(key, orderInvestigateRecords.get(key).size());
            totalAmount = totalAmount + orderInvestigateRecords.get(key).size();
        }
        modelAndView.addObject("total", total);
        modelAndView.addObject("totalAmount", totalAmount);
        
        DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        modelAndView.addObject("fmt", fmt);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param roundCode
     * @return
     */
    @RequestMapping(value = "/{roundCode}/zip", method = RequestMethod.GET)
    public ModelAndView zip(@PathVariable("roundCode") String roundCode) {
        
        ModelAndView modelAndView = new ModelAndView("course/online/online-round-zip");
        
        modelAndView.addObject("roundCode", roundCode);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param roundCode
     * @return
     */
    @RequestMapping(value = "/{roundCode}/zip", method = RequestMethod.PATCH)
    public @ResponseBody String onZip(@PathVariable("roundCode") String roundCode) {
        
        Result result = new Result();
        
        try {
            
            Map<String, List<CourseRound>> rounds = onlineRoundService.listCourseRoundByGroup(roundCode);
            
            Product product =  rounds.entrySet().iterator().next().getValue().get(0).getProduct();
            
            String filename = org.apache.commons.lang3.StringUtils.replace(product.getName(), " ", "-");
            
            zipHandler.zipFile(uploadPath, filename, null, filename, rounds);
            
            CourseRoundResource courseRoundResource = onlineRoundService.loadCourseRoundResource(roundCode);
            
            if(courseRoundResource == null) {
                courseRoundResource = new CourseRoundResource(roundCode, filename + ".zip");
                dataService.save(courseRoundResource);
            } else {
                courseRoundResource.editSource(filename + ".zip");
            }
            
            result.success().message("打包成功");
            
        } catch (BusinessException e) {
            
            result.fail().message(e.getMessage());
            
        } catch (Exception e) {
            
            logger.error("onZip() error", e);
            result.fail().message("打包失败");
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * Do export zip file
     * 
     * @param roundCode
     * @return
     */
    @RequestMapping(value = "/{roundCode}/zip-export" , method = RequestMethod.GET)
    public ModelAndView onExportZip(@PathVariable("roundCode") String roundCode) {
        
        CourseRoundResource courseRoundResource = onlineRoundService.loadCourseRoundResource(roundCode);
        
        ModelAndView modelAndView = new ModelAndView(new DownloadTemplateView(courseRoundResource.getSource(), uploadPath));
        
        return modelAndView;
    }
    
    /**
     * 
     * @param roundCode
     * @param roundId
     * @return
     */
    @RequestMapping(value = "/{roundCode}/rounds/{roundId}/qrcode-upload", method = RequestMethod.GET)
    public ModelAndView qrcodeUpload(@PathVariable("roundCode") String roundCode,
                                     @PathVariable("roundId") Long roundId,
                                     @RequestParam("grouped") Boolean grouped){
        
        ModelAndView modelAndView = new ModelAndView("course/online/online-round-qrcode-upload");
        
        CourseRound courseRound = onlineRoundService.loadCourseRound(roundId);
        
        modelAndView.addObject("courseRound", courseRound);
        
        modelAndView.addObject("grouped", grouped);
        
        return modelAndView;
        
    }
    
    /**
     * 
     * @param roundCode
     * @param roundId
     * @param qrcode
     * @return
     */
    @RequestMapping(value = "/{roundCode}/rounds/{roundId}/qrcode-upload", method = RequestMethod.POST)
    public ModelAndView onQrcodeUpload(@PathVariable("roundCode") String roundCode,
                                          @PathVariable("roundId") Long roundId,
                                          @RequestParam("grouped") Boolean grouped,
                                          @RequestParam("qrcode") MultipartFile qrcode){
        ModelAndView modelAndView = new ModelAndView("redirect:/online-rounds/" + roundCode + "?grouped=" + grouped);
        
        try {
            
            CourseRound courseRound = onlineRoundService.loadCourseRound(roundId);
            
            onlineRoundService.saveUserQrcode(courseRound, qrcode);
            
        } catch(Exception e) {
            logger.error("#onQrcodeUpload() ", e);
        } 
        
        return modelAndView;
        
    }
    
    
    

}
